package com.me.supermario.entities;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.me.supermario.screens.Play;

@SuppressWarnings("unused")
public class Fireball extends Sprite {
	
	private Vector2 velocity = new Vector2 ();
	private TiledMapTileLayer collisionLayer;
	private float speed = 200 , gravity = 200 * 1.8f, increment, animationTime = 0;
	private float oldSpeed=speed;
	private boolean firstTime = true;
	private String blockedKey = "blocked";
	protected Rectangle rect = new Rectangle ();
	private Player giocatore;
	private boolean fireDeadState = false;
	
	//ANIMAZIONI
	private static TextureAtlas fireAtlas = new TextureAtlas("com/me/img/fire.pack");
	private static Animation left = new Animation (1/6f, fireAtlas.findRegions("left"));
	private static Animation right = new Animation (1/6f, fireAtlas.findRegions("right"));
	
	
	public Fireball (TiledMapTileLayer collisionLayer, Player player){
		super(left.getKeyFrame(0));
		this.giocatore = player;
		this.collisionLayer = collisionLayer;
		//fireball
		left.setPlayMode(Animation.LOOP);
		right.setPlayMode(Animation.LOOP);
	
		/*if( player.getVelocity().x<0 )
			speed = 200;
		if(player.getVelocity().x==0)
			speed = 200;
		if(player.getVelocity().x>0)
			speed = 200;*/
		
	} //costruttore

	public void draw (SpriteBatch spritebatch) {
		update(Gdx.graphics.getDeltaTime());
		super.draw(spritebatch);
	}

	
	private boolean isCellEnemyBlocked(float x, float y) {
		Cell cell = collisionLayer.getCell((int) (x / collisionLayer.getTileWidth()), (int) (y / collisionLayer.getTileHeight()));
		return cell != null && cell.getTile() != null && cell.getTile().getProperties().containsKey(blockedKey);
	}
	
	
	private void update(float delta) {
		velocity.y -= gravity*delta;

		if (fireDeadState)
			velocity.set(0,0);

		//salva le vecchie posizioni
		//float oldX = getX(); 
		float oldY = getY();
		//settiamo due valori booleani: uno per vedere se collidiamo nell'asse X, uno per l'asse Y
		//boolean collisionX = false; 
		boolean collisionY = false;

		// muovi in x
		setX(getX() + velocity.x * delta);

		// calculate the increment for step in #collidesLeft() and #collidesRight()
		increment = collisionLayer.getTileWidth();
		increment = getWidth() < increment ? getWidth() / 2 : increment / 2;

		// muovi in Y
		setY(getY() + velocity.y * delta * 5f);

		// calculate the increment for step in #collidesBottom() and #collidesTop()
		increment = collisionLayer.getTileHeight();
		increment = getHeight() < increment ? getHeight() / 2 : increment / 2;

		if(velocity.y < 0){ // stai andando giu'
			collisionY = collidesBottom();

		}
		else if(velocity.y > 0) // stai andando su
			collisionY = collidesTop();

		// gestisci la collisione in Y
		if(collisionY) {
			setY(oldY);
			velocity.y = 0;
		}
		
		boolean pathX = false;
		
		if(velocity.x < 0){ // stai andando a sinistra
			pathX = collidesLeft();
		}else if(velocity.x > 0){ // stai andando a destra
			pathX = collidesRight();
		}
		if (pathX){
			//setX(oldX - velocity.x*delta);
			//cambiadirezione
			//setX(oldX);
		/*	if (velocity.x < 0){
				velocity.x = speed;
				this.oldSpeed = velocity.x;
				setX(getX() + velocity.x * delta);
				System.out.println (velocity.x);
			}
			else if (velocity.x > 0){
				velocity.x = -speed;
				this.oldSpeed = velocity.x;
				setX(getX() + velocity.x * delta);
				System.out.println (velocity.x);
				}*/
			if (velocity.x<0){
					velocity.set(0,0);
					setPosition(-20,-20);
					fireDeadState = true;
			}
			else if (velocity.x > 0){
				velocity.set(0,0);
				fireDeadState = true;
				setPosition(-20,-20);
			}
		}
		
		//aggiorna l'animazione
		animationTime += delta;
		setRegion(velocity.x < 0 ? left.getKeyFrame(animationTime) : right.getKeyFrame(animationTime));
	
		this.oldSpeed = velocity.x;
		//System.out.println ("FINE: Velocita' = " + velocity.x);
		
		fireCollisionWithEnemy();
		fireCollisionWithGuscio();
		
	}


	protected Rectangle rectangle() {
		return new Rectangle(this.getX(), this.getY(), this.getWidth(), this.getHeight());
	}
	
	protected void fireCollisionWithEnemy() {
		Array<Goomba> goombas = Play.getEnemies();
		Rectangle fireRect = rectangle();
		fireRect.set(this.getX(), this.getY(), this.getWidth(), this.getHeight());
		for(Goomba goomba : goombas) {
			Rectangle eRect = goomba.rectangle();
			if(eRect.overlaps(fireRect)) {
				if (! goomba.getDeadState()){
					goomba.deadByTrample();
					fireDeadState = true;
				}//if !goomba.deadstate
			}// if erect goombas
		}//for goombas
	}
	
	protected void fireCollisionWithGuscio() {
		Array<Guscio> gusci = Play.getGusci();
		Rectangle fireRect = rectangle();
		fireRect.set(this.getX(), this.getY(), this.getWidth(), this.getHeight());
		for(Guscio guscio : gusci) {
			Rectangle eRect = guscio.rectangle();
			if(eRect.overlaps(fireRect)) {
				if (! guscio.getDeadState()){
					guscio.setDeadState();
					System.out.println("morto");
					fireDeadState = true;
				}//if !goomba.deadstate
			}// if erect goombas
		}//for goombas
	}

	private boolean isCellBlocked(float x, float y) {
		Cell cell = collisionLayer.getCell((int) (x / collisionLayer.getTileWidth()), (int) (y / collisionLayer.getTileHeight()));
		return cell != null && cell.getTile() != null && cell.getTile().getProperties().containsKey(blockedKey);
	}

	public boolean collidesRight() {
		for(float step = 0; step < getHeight(); step += increment)
			if(isCellBlocked(getX() + getWidth() , getY() + step))
				return true;
		return false;
	}

	public boolean collidesLeft() {
		for(float step = 0; step < getHeight(); step += increment)
			if(isCellBlocked(getX(), getY() + step))
				return true;
		return false;
	}
	
	public boolean collidesTop() {
		for(float step = 0; step < getWidth(); step += increment)
			if(isCellBlocked(getX() + step, getY() + getHeight())){
				return true;
			}
		return false;
	}

	public boolean collidesBottom() {
		for(float step = 0; step < getWidth(); step += increment)
			if(isCellBlocked(getX() + step, getY())){
				return true;
			}
		return false;

	}
	
	public TiledMapTileLayer getCollisionLayer() {
		return collisionLayer;
	}

	public boolean getDeadState() {
		return fireDeadState;
	}
	
	public void setFireDeadState (boolean b) {
		fireDeadState = b;
	}
	
	public float getVelocityX(){
		return velocity.x;
	}
	
	public float getVelocityY(){ 
		return velocity.y;
	}
	
	public void setVelocityX( float newx ){
		velocity.x = newx;
	}
	
	public void setVelocityY( float newy ){
		velocity.y = newy;
	}

}
